<template>
  <div class="video-call-container">
    <div class="video-controls">
      <el-button type="primary" @click="handleStartVideo" :disabled="isVideoStarted">
        <i class="el-icon-video-camera"></i> 开始视频
      </el-button>
      <el-button type="danger" @click="stopVideo" :disabled="!isVideoStarted">
        <i class="el-icon-video-camera-solid"></i> 停止视频
      </el-button>
      <el-button type="success" @click="sendInvitation" :disabled="!isVideoStarted || isConnected">
        <i class="el-icon-connection"></i> 发起视频通话
      </el-button>
      <el-button type="warning" @click="hangUp" :disabled="!isConnected">
        <i class="el-icon-close"></i> 挂断
      </el-button>
    </div>
    <div class="video-display">
      <div class="video-box">
        <video ref="localVideo" autoplay playsinline></video>
        <div class="video-label">本地视频</div>
      </div>
      <div class="video-box">
        <video ref="remoteVideo" autoplay playsinline></video>
        <div class="video-label">远程视频</div>
      </div>
    </div>
    <div class="user-id-display">
      <span class="user-id">用户ID: </span>
      <span class="user-id">{{ userId }}</span>
      <el-button type="primary" class="copy-button" @click="copyUserId">复制</el-button>
      <div class="user-guide">
        <p v-if="!isConnected">
          <i class="el-icon-info"></i>
          等待他人邀请时，只需要记住或复制您的用户ID并分享给对方即可，无需其他操作。
        </p>
        <p v-if="!isConnected" class="guide-steps">
          收到邀请后：<br>
          1. 点击"接受"按钮<br>
          2. 允许使用摄像头<br>
          3. 等待连接建立
        </p>
      </div>
    </div>
  </div>
</template>

<script>
export default {
  name: 'VideoCall',
  data() {
    return {
      socket: null,
      socketRead: false,
      localStream: null,
      peerConnection: null,
      peerStarted: false,
      isVideoStarted: false,
      isConnected: false,
      userId: '',
      mediaConstraints: {
        video: true,
        audio: false
      },
      heartbeatInterval: null,
      remoteUserId: ''
    }
  },
  created() {
    this.initWebSocket()
  },
  beforeDestroy() {
    this.stop()
    this.stopHeartbeat()
    if (this.socket) {
      this.socket.close()
    }
  },
  methods: {
    initWebSocket() {
      // 生成一个更独特的用户ID，包含时间戳和随机数
      const timestamp = new Date().getTime();
      const randomNum = Math.floor(Math.random() * 10000);
      const browserInfo = navigator.userAgent.includes('Chrome') ? 'Chrome' :
                         navigator.userAgent.includes('Firefox') ? 'Firefox' :
                         navigator.userAgent.includes('Safari') ? 'Safari' : 'Other';
      this.userId = `${browserInfo}_${timestamp}_${randomNum}`;

      // 使用本地存储来保存当前浏览器的用户ID
      localStorage.setItem('videoUserId', this.userId);

      // 动态获取WebSocket服务器地址
      const wsProtocol = window.location.protocol === 'https:' ? 'wss:' : 'ws:';
      const wsHost = window.location.hostname;
      const wsPort = '9228'; // 修改为实际的后端端口
      const socketUrl = `${wsProtocol}//${wsHost}:${wsPort}/msgServer/${this.userId}`;

      console.log('WebSocket连接地址:', socketUrl);

      this.socket = new WebSocket(socketUrl);

      this.socket.onopen = () => {
        console.log("成功连接到服务器...");
        this.socketRead = true;
        this.startHeartbeat();
        this.broadcastOnlineStatus();
      };

      this.socket.onclose = (e) => {
        console.log('与服务器连接关闭: ' + e.code);
        this.socketRead = false;
        this.stopHeartbeat();
      };

      this.socket.onmessage = (res) => {
        const message = res.data;
        if (message === "心跳") {
          return;
        }
        try {
          const evt = JSON.parse(message);
          console.log("收到消息:", evt);

          if (evt.type === 'invitation') {
            // 播放提示音
            const audio = new Audio('/notification.mp3')
            audio.play().catch(e => console.log('无法播放提示音:', e))

            // 显示桌面通知
            if (Notification.permission === "granted") {
              new Notification("视频通话邀请", {
                body: `用户 ${evt.from} 邀请您进行视频通话`,
                icon: "/video-call-icon.png"
              })
            }

            // 显示确认对话框
            this.$confirm(`用户 ${evt.from} 邀请您进行视频通话`, '视频通话邀请', {
              confirmButtonText: '接受',
              cancelButtonText: '拒绝',
              type: 'info',
              showClose: false,
              closeOnClickModal: false,
              closeOnPressEscape: false,
              center: true,
              customClass: 'video-invitation-dialog'
            }).then(() => {
              this.handleStartVideo().then(() => {
                this.connect(evt.from)
              })
            }).catch(() => {
              this.sendMessage({
                type: 'reject',
                to: evt.from,
                from: this.userId
              })
            })
            return
          }

          if (evt.type === 'reject') {
            this.$message({
              type: 'info',
              message: `对方拒绝了视频通话`
            })
            return
          }

          if (evt.type === 'offer') {
            console.log("接收到offer,设置offer,发送answer....")
            this.onOffer(evt)
          } else if (evt.type === 'answer' && this.peerStarted) {
            console.log('接收到answer,设置answer SDP')
            this.onAnswer(evt)
          } else if (evt.type === 'candidate' && this.peerStarted) {
            console.log('接收到ICE候选者..')
            this.onCandidate(evt)
          } else if (evt.type === 'bye') {
            console.log("对方已挂断");
            this.$message({
              type: 'info',
              message: '对方已结束通话'
            });
            this.stop();
          }
        } catch (error) {
          console.error("消息解析错误:", error)
        }
      }
    },
    startHeartbeat() {
      this.heartbeatInterval = setInterval(() => {
        if (this.socket && this.socket.readyState === WebSocket.OPEN) {
          this.socket.send("心跳")
        }
      }, 30000)
    },
    stopHeartbeat() {
      if (this.heartbeatInterval) {
        clearInterval(this.heartbeatInterval)
        this.heartbeatInterval = null
      }
    },
    handleStartVideo() {
      return new Promise((resolve, reject) => {
        console.log('设备信息:', {
          userAgent: navigator.userAgent,
          protocol: window.location.protocol,
          hostname: window.location.hostname,
          isSecureContext: window.isSecureContext,
          hasGetUserMedia: !!navigator.mediaDevices?.getUserMedia
        });

        // 检查是否为Chrome浏览器
        const isChrome = /Chrome/.test(navigator.userAgent) && /Google Inc/.test(navigator.vendor);
        // 检查是否为本地网络
        const isLocalNetwork = window.location.hostname === 'localhost' ||
                             window.location.hostname === '127.0.0.1' ||
                             window.location.hostname.startsWith('192.168.') ||
                             window.location.hostname.startsWith('10.');
        // 检查是否为HTTPS
        const isHttps = window.location.protocol === 'https:';

        if (!isHttps && !isLocalNetwork) {
          if (isChrome) {
            this.$alert(`当前使用的是不安全的HTTP连接(${window.location.href})，Chrome浏览器要求使用安全连接才能访问摄像头。

解决方法：
1. 临时解决（仅限开发测试）：
   a. 右键点击桌面上的Chrome快捷方式
   b. 选择"属性"
   c. 在"目标"框的最后添加以下参数（注意前面要有空格）：
      --unsafely-treat-insecure-origin-as-secure="${window.location.href}" --user-data-dir=/tmp/foo

2. 推荐的解决方法：
   - 使用HTTPS访问
   - 或使用localhost访问`, '安全提示', {
              confirmButtonText: '我知道了',
              type: 'warning',
              duration: 0,
              showClose: true
            });
            reject(new Error('不安全的连接'));
            return;
          } else {
            this.$alert(`当前使用的是不安全的HTTP连接，浏览器要求使用安全连接才能访问摄像头。

请使用以下方式之一访问：
1. 使用HTTPS访问
2. 使用localhost访问
3. 或者换用Chrome浏览器（可以通过特殊参数允许HTTP访问）`, '安全提示', {
              confirmButtonText: '我知道了',
              type: 'warning'
            });
            reject(new Error('不安全的连接'));
            return;
          }
        }

        // 检查是否支持getUserMedia
        if (!navigator.mediaDevices?.getUserMedia) {
          const browserInfo = {
            isChrome: /Chrome/.test(navigator.userAgent),
            isFirefox: /Firefox/.test(navigator.userAgent),
            isEdge: /Edg/.test(navigator.userAgent),
            isSafari: /Safari/.test(navigator.userAgent) && !/Chrome/.test(navigator.userAgent),
            version: navigator.userAgent.match(/(?:Chrome|Firefox|Safari|Edge?)\/(\d+)/)?.[1] || 'unknown'
          };

          let message = '您的浏览器不支持摄像头访问，请：\n';
          if (browserInfo.isChrome && parseInt(browserInfo.version) < 47) {
            message += `当前Chrome版本(${browserInfo.version})过低，需要47以上版本`;
          } else if (browserInfo.isFirefox && parseInt(browserInfo.version) < 44) {
            message += `当前Firefox版本(${browserInfo.version})过低，需要44以上版本`;
          } else {
            message += '1. 使用最新版本的Chrome/Firefox/Edge浏览器\n' +
                      '2. 确保浏览器已更新到最新版本\n' +
                      '3. 如果是移动设备，请使用系统自带浏览器';
          }

          this.$message({
            type: 'error',
            message: message,
            duration: 8000,
            showClose: true
          });
          reject(new Error('浏览器不支持'));
          return;
        }

        // 尝试访问摄像头
        const constraints = {
          video: {
            width: { ideal: 640 },
            height: { ideal: 480 }
          },
          audio: false
        };

        navigator.mediaDevices.getUserMedia(constraints)
          .then(stream => {
            console.log('成功获取视频流');
            this.localStream = stream;
            const videoElement = this.$refs.localVideo;
            if (videoElement) {
              try {
                videoElement.srcObject = stream;
                videoElement.onloadedmetadata = () => {
                  videoElement.play().catch(e => {
                    console.error('视频播放失败:', e);
                    this.$message.error('视频播放失败，请刷新页面重试');
                    reject(e);
                  });
                  this.isVideoStarted = true;
                  this.$message.success('摄像头已开启');
                  resolve();
                };
              } catch (error) {
                console.error('设置视频流失败:', error);
                this.$message.error('设置视频流失败，请刷新页面重试');
                reject(error);
              }
            }
          })
          .catch(err => {
            console.error('获取视频流失败:', err);
            let message = '';

            switch(err.name) {
              case 'NotFoundError':
                message = '未找到摄像头设备，请检查：\n' +
                         '1. 摄像头是否正确连接\n' +
                         '2. 设备管理器中摄像头是否正常\n' +
                         '3. 是否被其他程序占用（如Teams、Zoom等）';
                break;
              case 'NotAllowedError':
              case 'PermissionDeniedError':
                message = '摄像头访问被拒绝，请：\n' +
                         '1. 点击地址栏左侧的摄像头图标\n' +
                         '2. 选择"允许"\n' +
                         '3. 刷新页面重试\n' +
                         '4. 如果还是不行，请检查系统设置中的摄像头权限';
                break;
              case 'NotReadableError':
                message = '摄像头被占用，请：\n' +
                         '1. 关闭其他可能使用摄像头的程序\n' +
                         '2. 刷新页面重试\n' +
                         '3. 如果还不行，请重启电脑';
                break;
              default:
                message = `摄像头访问失败(${err.name})，请：\n` +
                         '1. 使用Chrome/Firefox/Edge最新版本\n' +
                         '2. 检查摄像头连接\n' +
                         '3. 允许浏览器访问摄像头\n' +
                         '4. 确保使用HTTPS或localhost访问';
            }

            this.$message({
              type: 'error',
              message: message,
              duration: 8000,
              showClose: true
            });
            reject(err);
          });
      });
    },
    stopVideo() {
      if (this.localStream) {
        this.localStream.getTracks().forEach(track => track.stop())
        this.$refs.localVideo.srcObject = null
        this.localStream = null
        this.isVideoStarted = false
      }
    },
    prepareNewConnection() {
      // 配置ICE服务器
      const pc_config = {
        iceServers: [
          {
            urls: [
              'stun:stun.l.google.com:19302',
              'stun:stun1.l.google.com:19302',
              'stun:stun2.l.google.com:19302'
            ]
          }
        ],
        iceTransportPolicy: "all"
      };

      let peer = null;
      try {
        peer = new RTCPeerConnection(pc_config);
        console.log('创建RTCPeerConnection成功');

        // 监听ICE候选者
        peer.onicecandidate = (event) => {
          if (event.candidate) {
            console.log("发现ICE候选者:", event.candidate);
            this.sendMessage({
              type: "candidate",
              from: this.userId,
              to: this.remoteUserId,
              sdpMLineIndex: event.candidate.sdpMLineIndex,
              sdpMid: event.candidate.sdpMid,
              candidate: event.candidate.candidate
            });
          } else {
            console.log("ICE候选者收集完成");
          }
        };

        // 监听ICE收集状态
        peer.onicegatheringstatechange = (event) => {
          console.log("ICE收集状态:", peer.iceGatheringState);
        };

        // 监听连接状态变化
        peer.onconnectionstatechange = (event) => {
          console.log('连接状态变化:', peer.connectionState);
          switch(peer.connectionState) {
            case 'connected':
              this.$message.success('视频连接已建立');
              this.isConnected = true;
              break;
            case 'disconnected':
              this.$message.warning('视频连接已断开，正在重连...');
              break;
            case 'failed':
              console.error('连接失败，详细信息:', {
                iceConnectionState: peer.iceConnectionState,
                iceGatheringState: peer.iceGatheringState,
                signalingState: peer.signalingState
              });
              this.$message.error('视频连接失败，请重新发起通话');
              this.hangUp();
              break;
          }
        };

        // 监听ICE连接状态
        peer.oniceconnectionstatechange = (event) => {
          console.log("ICE连接状态:", peer.iceConnectionState);
          if (peer.iceConnectionState === 'failed') {
            console.error('ICE连接失败，可能的原因：', {
              iceConnectionState: peer.iceConnectionState,
              iceGatheringState: peer.iceGatheringState,
              signalingState: peer.signalingState
            });
          }
        };

        // 监听信令状态
        peer.onsignalingstatechange = (event) => {
          console.log("信令状态:", peer.signalingState);
        };

        // 处理远程视频流
        peer.ontrack = (event) => {
          console.log("收到远程视频流:", event.streams);
          if (event.streams && event.streams[0]) {
            const remoteVideo = this.$refs.remoteVideo;
            if (remoteVideo) {
              remoteVideo.srcObject = event.streams[0];
              remoteVideo.onloadedmetadata = () => {
                remoteVideo.play().catch(e => {
                  console.error('远程视频播放失败:', e);
                  this.$message.error('远程视频播放失败，请刷新重试');
                });
              };
              this.isConnected = true;
              this.$message.success('远程视频已连接');
            }
          }
        };

        // 添加本地视频流
        if (this.localStream) {
          console.log('添加本地视频流到连接');
          this.localStream.getTracks().forEach(track => {
            console.log('添加视频轨道:', track);
            peer.addTrack(track, this.localStream);
          });
        } else {
          console.error('本地视频流不存在，请先开启摄像头');
          this.$message.error('请先开启摄像头');
          return null;
        }
      } catch (e) {
        console.error("创建RTCPeerConnection失败，错误：", e);
        this.$message.error('创建连接失败，请刷新页面重试');
        return null;
      }

      return peer;
    },
    onOffer(evt) {
      console.log("收到offer, 准备建立连接...", evt);
      this.remoteUserId = evt.from; // 保存发送方的ID
      
      if (!this.isVideoStarted) {
        console.error('本地视频未开启，无法接受连接');
        this.$message.error('请先开启视频再接受连接');
        this.sendMessage({
          type: 'reject',
          to: evt.from,
          from: this.userId,
          reason: 'local_video_not_started'
        });
        return;
      }

      if (!this.localStream) {
        console.error('本地视频流不存在');
        this.$message.error('本地视频流不存在，请刷新页面重试');
        this.sendMessage({
          type: 'reject',
          to: evt.from,
          from: this.userId,
          reason: 'no_local_stream'
        });
        return;
      }

      this.setOffer(evt)
        .then(() => {
          console.log('成功设置远程描述，准备发送answer...');
          return this.sendAnswer(evt);
        })
        .then(() => {
          console.log('Answer发送成功');
          this.peerStarted = true;
        })
        .catch(error => {
          console.error('处理offer失败:', error);
          this.$message.error('连接失败，请重试');
          this.sendMessage({
            type: 'reject',
            to: evt.from,
            from: this.userId,
            reason: 'offer_processing_failed',
            error: error.message
          });
          this.stop();
        });
    },
    setOffer(evt) {
      if (this.peerConnection) {
        console.warn('peerConnection已存在, 正在重置连接...');
        this.peerConnection.close();
        this.peerConnection = null;
      }

      console.log('创建新的点对点连接...');
      this.peerConnection = this.prepareNewConnection();
      if (!this.peerConnection) {
        return Promise.reject(new Error('创建点对点连接失败'));
      }

      console.log('设置远程描述...', evt.sdp);
      const rtcSessionDescription = new RTCSessionDescription({
        type: 'offer',
        sdp: evt.sdp
      });
      return this.peerConnection.setRemoteDescription(rtcSessionDescription)
        .catch(error => {
          console.error('设置远程描述失败:', error);
          throw new Error(`设置远程描述失败: ${error.message}`);
        });
    },
    sendAnswer(evt) {
      if (!this.peerConnection) {
        return Promise.reject(new Error('peerConnection不存在'));
      }

      console.log('创建Answer...');
      return this.peerConnection.createAnswer({
        offerToReceiveVideo: true,
        offerToReceiveAudio: false
      })
        .then(sessionDescription => {
          console.log('设置本地描述...');
          return this.peerConnection.setLocalDescription(sessionDescription)
            .then(() => {
              console.log("发送Answer SDP");
              this.sendMessage({
                type: "answer",
                from: this.userId,
                to: this.remoteUserId,
                sdp: sessionDescription.sdp
              });
            });
        });
    },
    onAnswer(evt) {
      console.log("收到Answer, 建立连接...");
      if (!this.peerConnection) {
        console.error('peerConnection不存在!');
        return;
      }

      const rtcSessionDescription = new RTCSessionDescription({
        type: 'answer',
        sdp: evt.sdp
      });
      this.peerConnection.setRemoteDescription(rtcSessionDescription)
        .then(() => {
          console.log('远程描述设置成功，连接建立完成');
        })
        .catch(error => {
          console.error('设置远程描述失败:', error);
          this.$message.error('连接失败，请重试');
          this.stop();
        });
    },
    onCandidate(evt) {
      const candidate = new RTCIceCandidate({
        sdpMLineIndex: evt.sdpMLineIndex,
        sdpMid: evt.sdpMid,
        candidate: evt.candidate
      })
      console.log("接收到Candidate...")
      console.log(candidate)
      this.peerConnection.addIceCandidate(candidate)
    },
    sendSDP(sdp) {
      const text = JSON.stringify(sdp)
      console.log('发送sdp.....')
      console.log(text)
      this.socket.send(text)
    },
    sendCandidate(candidate) {
      const text = JSON.stringify(candidate)
      console.log(text)
      this.socket.send(text)
    },
    connect(to) {
      console.log('尝试建立连接:', {
        to: to,
        peerStarted: this.peerStarted,
        hasLocalStream: !!this.localStream,
        socketReady: this.socketRead
      });

      if (!this.peerStarted && this.localStream && this.socketRead) {
        this.remoteUserId = to;  // 保存远程用户ID
        console.log('开始建立WebRTC连接...');
        
        // 创建新的连接
        this.peerConnection = this.prepareNewConnection();
        if (!this.peerConnection) {
          this.$message.error('创建连接失败，请重试');
          return;
        }

        // 创建和发送offer
        this.peerConnection.createOffer({
          offerToReceiveVideo: true,
          offerToReceiveAudio: false
        })
          .then(sessionDescription => {
            console.log('设置本地描述...');
            return this.peerConnection.setLocalDescription(sessionDescription)
              .then(() => {
                console.log("发送offer SDP");
                this.sendMessage({
                  type: "offer",
                  from: this.userId,
                  to: this.remoteUserId,
                  sdp: sessionDescription.sdp
                });
                this.peerStarted = true;
              });
          })
          .catch(error => {
            console.error('创建offer失败:', error);
            this.$message.error('创建连接失败，请重试');
            this.stop();
          });
      } else {
        console.warn('无法建立连接:', {
          peerStarted: this.peerStarted,
          hasLocalStream: !!this.localStream,
          socketReady: this.socketRead
        });
        
        let errorMessage = '';
        if (!this.localStream) {
          errorMessage = '请先开启摄像头';
        } else if (!this.socketRead) {
          errorMessage = '网络连接异常，请刷新页面重试';
        } else if (this.peerStarted) {
          errorMessage = '已有一个连接正在进行中';
        }
        
        this.$message.error(errorMessage || '无法建立连接，请检查网络和摄像头');
      }
    },
    hangUp() {
      console.log("挂断.");
      // 发送挂断消息给对方
      if (this.remoteUserId) {
        this.sendMessage({
          type: 'bye',
          from: this.userId,
          to: this.remoteUserId
        });
      }
      this.stop();
    },
    stop() {
      if (this.peerConnection) {
        this.peerConnection.close();
        this.peerConnection = null;
        this.peerStarted = false;
        this.isConnected = false;
      }
      if (this.$refs.remoteVideo) {
        this.$refs.remoteVideo.srcObject = null;
      }
      // 清除远程用户ID
      this.remoteUserId = '';
    },
    sendInvitation() {
      if (!this.isVideoStarted) {
        this.$message.warning("请先开启视频");
        return;
      }

      // 显示输入对方ID的对话框
      this.$prompt('请输入对方的ID', '发起视频通话', {
        confirmButtonText: '确定',
        cancelButtonText: '取消',
        inputPlaceholder: '请输入完整的用户ID'
      }).then(({ value }) => {
        if (value) {
          if (value === this.userId) {
            this.$message.error('不能连接自己');
            return;
          }
          console.log('准备发送邀请给:', value);
          this.remoteUserId = value; // 保存目标用户ID
          this.sendDirectInvitation(value);
        }
      }).catch(() => {});
    },
    sendDirectInvitation(targetUserId) {
      console.log('发送视频邀请:', {
        from: this.userId,
        to: targetUserId
      });

      this.sendMessage({
        type: 'invitation',
        from: this.userId,
        to: targetUserId
      });

      this.$message({
        type: 'info',
        message: `已向用户 ${targetUserId} 发送视频邀请，等待接受...`,
        duration: 0,
        showClose: true
      });
    },
    getOnlineUsers() {
      // 这里简单实现，实际项目中应该从服务器获取
      const currentUserId = localStorage.getItem('videoUserId')
      const onlineUsers = []

      // 遍历所有localStorage，找出其他视频用户
      for (let i = 0; i < localStorage.length; i++) {
        const key = localStorage.key(i)
        if (key.startsWith('videoUserId_')) {
          const userId = localStorage.getItem(key)
          if (userId && userId !== currentUserId) {
            onlineUsers.push(userId)
          }
        }
      }

      return onlineUsers
    },
    sendMessage(message) {
      if (this.socket && this.socket.readyState === WebSocket.OPEN) {
        console.log('发送消息:', message);
        try {
          this.socket.send(JSON.stringify(message));
        } catch (error) {
          console.error('发送消息失败:', error);
          this.$message.error('发送消息失败，请刷新页面重试');
          // 如果是视频相关的消息，停止连接
          if (message.type === 'offer' || message.type === 'answer' || message.type === 'candidate') {
            this.stop();
          }
        }
      } else {
        console.error('WebSocket未连接，无法发送消息');
        this.$message.error('网络连接异常，请刷新页面重试');
        this.stop();
      }
    },
    // 广播在线状态，让其他浏览器知道有新用户加入
    broadcastOnlineStatus() {
      if (this.socket && this.socket.readyState === WebSocket.OPEN) {
        this.sendMessage({
          type: 'online',
          from: this.userId,
          browserType: navigator.userAgent
        })
      }
    },
    copyUserId() {
      const userId = this.userId
      const input = document.createElement('input')
      input.value = userId
      document.body.appendChild(input)
      input.select()
      document.execCommand('copy')
      document.body.removeChild(input)
      this.$message({
        type: 'success',
        message: '用户ID已复制到剪贴板'
      })
    }
  }
}
</script>

<style scoped>
.video-call-container {
  padding: 20px;
  background: white;
  border-radius: 8px;
  box-shadow: 0 2px 12px rgba(0, 0, 0, 0.1);
}

.video-controls {
  margin-bottom: 20px;
  display: flex;
  gap: 10px;
  justify-content: center;
}

.video-display {
  display: flex;
  gap: 20px;
  justify-content: center;
}

.video-box {
  position: relative;
  width: 320px;
  height: 240px;
  background: #f5f7fa;
  border-radius: 8px;
  overflow: hidden;
}

.video-box video {
  width: 100%;
  height: 100%;
  object-fit: cover;
}

.video-label {
  position: absolute;
  bottom: 10px;
  left: 10px;
  background: rgba(0, 0, 0, 0.5);
  color: white;
  padding: 4px 8px;
  border-radius: 4px;
  font-size: 12px;
}

.user-id-display {
  background: #f0f7ff;
  padding: 10px;
  border-radius: 6px;
  margin-bottom: 20px;
  text-align: center;
  border: 1px dashed #409EFF;
}

.user-id {
  font-size: 16px;
  font-weight: bold;
  color: #409EFF;
  margin: 0 5px;
}

.copy-button {
  margin-left: 10px;
  padding: 2px 10px;
  font-size: 12px;
}

.user-guide {
  margin-top: 10px;
  font-size: 14px;
  color: #606266;
  text-align: left;
  padding: 10px;
  background: rgba(255, 255, 255, 0.8);
  border-radius: 4px;
}

.user-guide p {
  margin: 5px 0;
  line-height: 1.5;
}

.user-guide i {
  color: #409EFF;
  margin-right: 5px;
}

.guide-steps {
  color: #67C23A;
  font-size: 13px;
  padding-left: 20px;
}

/* 视频邀请对话框样式 */
:deep(.video-invitation-dialog) {
  border-radius: 8px;
  overflow: hidden;
  animation: shake 0.5s ease-in-out;
}

:deep(.video-invitation-dialog .el-dialog__header) {
  background: linear-gradient(135deg, #409EFF 0%, #3a8ee6 100%);
  padding: 20px;
  margin: 0;
}

:deep(.video-invitation-dialog .el-dialog__title) {
  color: white;
  font-size: 18px;
  display: flex;
  align-items: center;
  gap: 8px;
}

:deep(.video-invitation-dialog .el-dialog__title::before) {
  content: '';
  display: inline-block;
  width: 24px;
  height: 24px;
  background: url('/video-call-icon.png') no-repeat center;
  background-size: contain;
}

:deep(.video-invitation-dialog .el-dialog__body) {
  padding: 30px 20px;
  text-align: center;
  font-size: 16px;
}

:deep(.video-invitation-dialog .el-dialog__footer) {
  padding: 10px 20px 20px;
  text-align: center;
}

:deep(.video-invitation-dialog .el-button) {
  padding: 12px 30px;
  font-size: 16px;
  border-radius: 25px;
}

:deep(.video-invitation-dialog .el-button--primary) {
  background: linear-gradient(135deg, #67C23A 0%, #4caf50 100%);
  border: none;
}

:deep(.video-invitation-dialog .el-button--default) {
  border-color: #909399;
  color: #606266;
}

@keyframes shake {
  0%, 100% { transform: translateX(0); }
  25% { transform: translateX(-5px); }
  75% { transform: translateX(5px); }
}
</style>
